package com.javaear.zblog4java.system.plugin;

import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.ibatis.session.Configuration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.javaear.zblog4java.system.entity.BaseModel;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author aooer
 */
@Component
public class MapperContext{

    @Autowired
    private MybatisSqlSessionFactoryBean sqlSessionFactoryBean;

    private Map<String,Class> urlModelMap=new HashMap<>();

    /**
     * 获取当前uri对应的mapper 名称name
     * @return mapper Name
     */
    public String pickType() {
        return requestURI().substring(requestURI().lastIndexOf("/") + 1).split("-")[0];
    }

    /**
     * 获取当前request
     * @return request
     */
    public HttpServletRequest pickRequest() {
        return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    }

    public Class pickClass(){
        try {
            if(urlModelMap.isEmpty()) {
                Configuration configuration = sqlSessionFactoryBean.getObject().getConfiguration();
                configuration.getTypeAliasRegistry().getTypeAliases().entrySet().stream().forEach(type -> {
                    TableName tableName = type.getValue().getAnnotation(TableName.class);
                    if (tableName != null) {
                        urlModelMap.put(tableName.value(),type.getValue());
                    }
                });
            }
            return urlModelMap.get(pickType());
        }catch (Exception  e){
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取请求Model实例
     *
     * @return model
     */
    public BaseModel pickModel() {
        try {
            //根据请求uri，寻找对应的mapper，从mapper获取泛型model具体类型
            BaseModel model = (BaseModel) pickClass().newInstance();
            //获取requestParameterMap里边的参数，过滤空值属性，并且组装成map，若值为string[]，则取值最后一个元素
            Map<String, String> paramterMap = pickRequest().getParameterMap().entrySet().stream().filter(e -> !StringUtils.isEmpty(e.getValue()[0]))
                    .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().length > 0 ? e.getValue()[e.getValue().length - 1] : e.getValue()[0]));
            //remove掉后台自动更新的字段
            paramterMap.remove("modifyTime");paramterMap.remove("createTime");
            //把requestParameterMap属性赋值给具体model，并返回model
            BeanUtils.copyProperties(model, paramterMap);
            //如果请求类型为add，检查参数
            if(requestURI().endsWith("add.html")) model.check();
            return model;
        } catch ( Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取请求地址
     *
     * @return uri
     */
    private String requestURI() {
        return pickRequest().getRequestURI();
    }

}